import datetime
import json
import os
import sys
import tempfile
import zipfile

from PyQt5 import QtGui
from PyQt5.QtCore import QSettings, QSharedMemory, QTimer, Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (QAction, QApplication, QDialog, QFileDialog, QFormLayout, QHBoxLayout, QInputDialog,
                             QLabel, QLineEdit, QMainWindow, QMenu, QMenuBar, QMessageBox, QPushButton, QSystemTrayIcon,
                             QTabWidget, QTextEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget)


def is_already_running():
    """检查是否已有实例在运行"""
    import os
    import tempfile
    
    # 使用文件锁方法
    lock_file = os.path.join(tempfile.gettempdir(), "command_manager_tool.lock")
    
    try:
        # 尝试创建并锁定文件
        if os.path.exists(lock_file):
            # 检查锁文件是否有效（进程是否还在运行）
            try:
                with open(lock_file, 'r') as f:
                    pid = int(f.read().strip())
                # 检查进程是否存在
                import ctypes
                kernel32 = ctypes.windll.kernel32
                handle = kernel32.OpenProcess(1, False, pid)
                if handle:
                    kernel32.CloseHandle(handle)
                    return True
            except:
                # 锁文件无效，删除并继续
                os.remove(lock_file)
        
        # 创建新的锁文件
        with open(lock_file, 'w') as f:
            f.write(str(os.getpid()))
        return False
    except:
        return False


class CommandDialog(QDialog):
    """命令添加/编辑对话框"""
    def __init__(self, parent=None, command_name="", command_content="", sub_title=""):
        super().__init__(parent)
        self.setWindowTitle("添加/编辑命令")
        self.resize(400, 250)
        
        layout = QFormLayout()
        
        # 命令名称输入框
        self.name_input = QLineEdit(command_name)
        layout.addRow("命令名称:", self.name_input)
        
        # 次标题输入框
        self.sub_title_input = QLineEdit(sub_title)
        layout.addRow("次标题:", self.sub_title_input)
        
        # 命令内容输入框
        self.content_input = QLineEdit(command_content)
        layout.addRow("命令内容:", self.content_input)
        
        # 确定和取消按钮
        button_box = QHBoxLayout()
        self.ok_button = QPushButton("确定")
        self.cancel_button = QPushButton("取消")
        
        button_box.addWidget(self.ok_button)
        button_box.addWidget(self.cancel_button)
        layout.addRow(button_box)
        
        self.setLayout(layout)
        
        # 连接信号
        self.ok_button.clicked.connect(self.accept)
        self.cancel_button.clicked.connect(self.reject)
    
    def get_command_data(self):
        """获取输入的命令数据"""
        return {
            "name": self.name_input.text(),
            "sub_title": self.sub_title_input.text(),
            "content": self.content_input.text()
        }


class CommandManager(QMainWindow):
    """命令管理工具"""
    def __init__(self):
        super().__init__()
        
        # 单实例共享内存
        self.shared_memory = QSharedMemory("command_manager_tool")
            
        self.setWindowTitle("命令管理工具")
        self.resize(1200, 800)
        self.center_window()
        
        # 设置窗口图标
        icon_path = os.path.join(os.path.dirname(__file__), 'command.ico')
        if os.path.exists(icon_path):
            self.setWindowIcon(QIcon(icon_path))
        
        self.commands_data = {}
        # 支持打包后的文件路径读取
        if getattr(sys, 'frozen', False):
            # 打包后使用可执行文件所在目录
            self.json_file = os.path.join(os.path.dirname(sys.executable), 'commands.json')
        else:
            # 开发环境使用脚本所在目录
            self.json_file = os.path.join(os.path.dirname(__file__), 'commands.json')
        
        # 加载设置
        self.load_settings()
        self.load_commands()
        self.init_ui()
        self.init_tray_icon()
        
        # 应用当前主题
        self.apply_theme()

    def load_settings(self):
        """加载应用程序设置"""
        self.settings = QSettings("CommandManager", "CommandTool")
        # 默认启用自动保存
        self.auto_save_enabled = self.settings.value("auto_save_enabled", True, type=bool)
        # 默认使用浅色主题
        self.theme = self.settings.value("theme", "light", type=str)

    def save_settings(self):
        """保存应用程序设置"""
        self.settings.setValue("auto_save_enabled", self.auto_save_enabled)
        self.settings.setValue("theme", self.theme)

    def center_window(self):
        screen = QApplication.desktop().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2)

    def init_tray_icon(self):
        """初始化系统托盘图标"""
        # 创建托盘图标
        self.tray_icon = QSystemTrayIcon(self)
        
        # 设置图标
        icon_path = os.path.join(os.path.dirname(__file__), 'command.ico')
        if os.path.exists(icon_path):
            self.tray_icon.setIcon(QIcon(icon_path))
        else:
            # 如果没有图标文件，使用默认图标
            self.tray_icon.setIcon(QIcon())
        
        # 设置提示文本
        self.tray_icon.setToolTip("命令管理工具v1.0")
        
        # 创建托盘菜单
        tray_menu = QMenu()
        
        # 显示窗口
        show_action = QAction("显示窗口", self)
        show_action.triggered.connect(self.show_window)
        tray_menu.addAction(show_action)
        
        # 隐藏窗口
        hide_action = QAction("隐藏窗口", self)
        hide_action.triggered.connect(self.hide_window)
        tray_menu.addAction(hide_action)
        
        tray_menu.addSeparator()
        
        # 退出程序
        quit_action = QAction("退出", self)
        quit_action.triggered.connect(self.quit_application)
        tray_menu.addAction(quit_action)
        
        # 设置托盘菜单
        self.tray_icon.setContextMenu(tray_menu)
        
        # 连接托盘图标的激活信号
        self.tray_icon.activated.connect(self.on_tray_icon_activated)
        
        # 显示托盘图标
        self.tray_icon.show()

    def show_window(self):
        """显示窗口"""
        self.show()
        self.raise_()
        self.activateWindow()

    def hide_window(self):
        """隐藏窗口"""
        self.hide()

    def toggle_window(self):
        """切换窗口显示/隐藏"""
        if self.isVisible():
            self.hide()
        else:
            self.show()
            self.raise_()
            self.activateWindow()

    def on_tray_icon_activated(self, reason):
        """托盘图标激活事件"""
        if reason == QSystemTrayIcon.Trigger:  # 左键单击
            self.show_window()
        elif reason == QSystemTrayIcon.DoubleClick:
            self.toggle_window()

    def quit_application(self):
        """退出应用程序"""
        self.tray_icon.hide()
        self.shared_memory.detach()
        QApplication.quit()

    def closeEvent(self, event):
        """重写关闭事件，最小化到托盘"""
        event.ignore()
        self.hide()
        self.tray_icon.showMessage(
            "命令管理工具",
            "程序已最小化到系统托盘",
            QSystemTrayIcon.Information,
            2000
        )

    def backup_data(self):
        """备份数据到ZIP文件"""
        from datetime import datetime
        
        # 让用户选择保存路径
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        default_filename = f"commands_backup_{timestamp}.zip"
        
        file_path, _ = QFileDialog.getSaveFileName(
            self, 
            "保存备份文件", 
            default_filename, 
            "ZIP Files (*.zip)"
        )
        
        if not file_path:
            return  # 用户取消了操作
        
        try:
            # 创建临时目录
            with tempfile.TemporaryDirectory() as temp_dir:
                # 复制数据文件到临时目录
                temp_json_file = os.path.join(temp_dir, "commands.json")
                import shutil
                shutil.copy2(self.json_file, temp_json_file)
                
                # 创建ZIP文件
                with zipfile.ZipFile(file_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
                    zipf.write(temp_json_file, "commands.json")
                
                QMessageBox.information(self, "备份成功", f"数据已备份到:\n{file_path}")
        except Exception as e:
            QMessageBox.warning(self, "备份失败", f"备份数据时出错:\n{str(e)}")

    def toggle_auto_start(self, checked):
        """切换开机自启动设置"""
        if checked:
            QMessageBox.information(self, "设置", "开机自启动功能已开启（最小化启动）")
        else:
            QMessageBox.information(self, "设置", "开机自启动功能已关闭")

    def toggle_auto_save(self, checked):
        """切换自动保存设置"""
        self.auto_save_enabled = checked
        self.save_settings()
        
        # 更新待办事项页面的自动保存状态
        if hasattr(self, 'todo_page'):
            self.todo_page.set_auto_save_enabled(checked)
        
        status = "启用" if checked else "禁用"
        QMessageBox.information(self, "提示", f"待办事项自动保存已{status}")
    
    def toggle_theme(self, theme):
        """切换主题"""
        self.theme = theme
        self.save_settings()
        
        # 更新主题选择状态
        self.light_theme_action.setChecked(theme == "light")
        self.dark_theme_action.setChecked(theme == "dark")
        
        # 应用主题样式
        self.apply_theme()
    
    def apply_theme(self):
        """应用主题样式"""
        if self.theme == "dark":
            # 深色主题样式
            style_sheet = """
                QTabWidget::pane {
                    border: 1px solid #555;
                    background-color: #2b2b2b;
                }
                QTabBar::tab {
                    background-color: #3c3c3c;
                    color: white;
                    padding: 8px 16px;
                    border: 1px solid #555;
                    border-bottom: none;
                    border-top-left-radius: 4px;
                    border-top-right-radius: 4px;
                }
                QTabBar::tab:selected {
                    background-color: #2b2b2b;
                    border-bottom: 1px solid #2b2b2b;
                }
                QTabBar::tab:hover:!selected {
                    background-color: #4a4a4a;
                }
                QWidget {
                    background-color: #2b2b2b;
                    color: white;
                }
                QTreeWidget {
                    background-color: #2b2b2b;
                    color: white;
                    border: 1px solid #555;
                }
                QTreeWidget::item {
                    background-color: #2b2b2b;
                }
                QTreeWidget::item:alternate {
                    background-color: #3c3c3c;
                }
                QTreeWidget::item:selected {
                    background-color: #0078d4;
                    color: white;
                }
                QLineEdit, QPushButton, QTextEdit {
                    background-color: #3c3c3c;
                    color: white;
                    border: 1px solid #555;
                }
                QLineEdit:focus, QPushButton:hover, QTextEdit:focus {
                    border: 1px solid #0078d4;
                }
                QMenuBar {
                    background-color: #2b2b2b;
                    color: white;
                }
                QMenuBar::item {
                    background-color: #2b2b2b;
                    color: white;
                }
                QMenuBar::item:selected {
                    background-color: #0078d4;
                }
                QMenu {
                    background-color: #2b2b2b;
                    color: white;
                    border: 1px solid #555;
                }
                QMenu::item {
                    background-color: #2b2b2b;
                    color: white;
                }
                QMenu::item:selected {
                    background-color: #0078d4;
                }
            """
        else:
            # 浅色主题样式（默认）
            style_sheet = """
                QTabWidget::pane {
                    border: 1px solid #c0c0c0;
                    background-color: white;
                }
                QTabBar::tab {
                    background-color: #f0f0f0;
                    color: black;
                    padding: 8px 16px;
                    border: 1px solid #c0c0c0;
                    border-bottom: none;
                    border-top-left-radius: 4px;
                    border-top-right-radius: 4px;
                }
                QTabBar::tab:selected {
                    background-color: white;
                    border-bottom: 1px solid white;
                }
                QTabBar::tab:hover:!selected {
                    background-color: #e0e0e0;
                }
                QWidget {
                    background-color: white;
                    color: black;
                }
                QTreeWidget {
                    background-color: white;
                    color: black;
                    border: 1px solid #c0c0c0;
                }
                QTreeWidget::item {
                    background-color: white;
                }
                QTreeWidget::item:alternate {
                    background-color: #f8f8f8;
                }
                QTreeWidget::item:selected {
                    background-color: #0078d4;
                    color: white;
                }
                QLineEdit, QPushButton, QTextEdit {
                    background-color: white;
                    color: black;
                    border: 1px solid #c0c0c0;
                }
                QLineEdit:focus, QPushButton:hover, QTextEdit:focus {
                    border: 1px solid #0078d4;
                }
                QMenuBar {
                    background-color: #f0f0f0;
                    color: black;
                }
                QMenuBar::item {
                    background-color: #f0f0f0;
                    color: black;
                }
                QMenuBar::item:selected {
                    background-color: #0078d4;
                    color: white;
                }
                QMenu {
                    background-color: white;
                    color: black;
                    border: 1px solid #c0c0c0;
                }
                QMenu::item {
                    background-color: white;
                    color: black;
                }
                QMenu::item:selected {
                    background-color: #0078d4;
                    color: white;
                }
            """
        
        self.setStyleSheet(style_sheet)
        # 同时应用到子组件
        self.tab_widget.setStyleSheet(style_sheet)
        self.todo_page.setStyleSheet(style_sheet)
        
        # 重新设置分类颜色，避免被主题样式覆盖
        if hasattr(self, 'content_tree'):
            self.update_tree_view()

    def show_about(self):
        """显示关于信息"""
        about_text = """
            命令管理工具
            
            版本: 1.0.0
            功能:
            - 命令和分类管理
            - 数据持久化存储
            - 快捷复制功能
            - 搜索功能
            - 待办事项管理
            
            作者: bai
        """
        QMessageBox.about(self, "关于", about_text.strip())

    def load_backup_data(self):
        """从ZIP文件加载备份数据"""
        import tempfile
        import zipfile
        
        # 让用户选择备份文件
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "选择备份文件",
            "",
            "ZIP Files (*.zip)"
        )
        
        if not file_path:
            return
        
        try:
            # 创建临时目录
            with tempfile.TemporaryDirectory() as temp_dir:
                # 解压ZIP文件
                with zipfile.ZipFile(file_path, 'r') as zip_ref:
                    zip_ref.extractall(temp_dir)
                
                # 查找JSON文件
                json_files = [f for f in os.listdir(temp_dir) if f.endswith('.json')]
                if not json_files:
                    QMessageBox.warning(self, "警告", "备份文件中未找到JSON数据文件")
                    return
                
                # 使用第一个找到的JSON文件
                json_file_path = os.path.join(temp_dir, json_files[0])
                
                # 读取数据
                with open(json_file_path, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                
                # 确认是否覆盖当前数据
                reply = QMessageBox.question(
                    self,
                    "确认",
                    "加载备份将覆盖当前数据，是否继续？",
                    QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No
                )
                
                if reply == QMessageBox.Yes:
                    # 备份当前数据
                    current_backup = self.json_file + ".backup"
                    if os.path.exists(self.json_file):
                        import shutil
                        shutil.copy2(self.json_file, current_backup)
                    
                    # 保存新数据
                    with open(self.json_file, 'w', encoding='utf-8') as f:
                        json.dump(data, f, ensure_ascii=False, indent=2)
                    
                    # 重新加载数据
                    self.load_commands()
                    
                    QMessageBox.information(self, "成功", "备份数据已成功加载")
        
        except Exception as e:
            QMessageBox.critical(self, "错误", f"加载备份失败: {str(e)}")

    def init_ui(self):
        # 菜单栏
        self.menu_bar = QMenuBar()
        self.file_menu = self.menu_bar.addMenu("文件")
        self.settings_menu = self.menu_bar.addMenu("设置")
        self.help_menu = self.menu_bar.addMenu("帮助")
        
        # 文件菜单项
        self.backup_action = QAction("备份数据", self)
        self.backup_action.triggered.connect(self.backup_data)
        self.file_menu.addAction(self.backup_action)
        
        self.load_backup_action = QAction("加载备份", self)
        self.load_backup_action.triggered.connect(self.load_backup_data)
        self.file_menu.addAction(self.load_backup_action)
        
        # 设置菜单项
        self.auto_start_action = QAction("开机自启动（最小化）", self)
        self.auto_start_action.setCheckable(True)
        self.auto_start_action.triggered.connect(self.toggle_auto_start)
        self.settings_menu.addAction(self.auto_start_action)
        
        # 自动保存选项
        self.auto_save_action = QAction("启用待办事项自动保存", self)
        self.auto_save_action.setCheckable(True)
        self.auto_save_action.setChecked(self.auto_save_enabled)
        self.auto_save_action.triggered.connect(self.toggle_auto_save)
        self.settings_menu.addAction(self.auto_save_action)
        
        # 主题切换选项
        self.theme_menu = self.settings_menu.addMenu("主题")
        
        self.light_theme_action = QAction("浅色主题", self)
        self.light_theme_action.setCheckable(True)
        self.light_theme_action.setChecked(self.theme == "light")
        self.light_theme_action.triggered.connect(lambda: self.toggle_theme("light"))
        self.theme_menu.addAction(self.light_theme_action)
        
        self.dark_theme_action = QAction("深色主题", self)
        self.dark_theme_action.setCheckable(True)
        self.dark_theme_action.setChecked(self.theme == "dark")
        self.dark_theme_action.triggered.connect(lambda: self.toggle_theme("dark"))
        self.theme_menu.addAction(self.dark_theme_action)
        
        # 帮助菜单项
        self.about_action = QAction("关于", self)
        self.about_action.triggered.connect(self.show_about)
        self.help_menu.addAction(self.about_action)
        
        self.setMenuBar(self.menu_bar)

        # 主布局
        self.main_widget = QWidget()
        self.setCentralWidget(self.main_widget)
        self.main_layout = QVBoxLayout()
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)
        self.main_widget.setLayout(self.main_layout)
        
        # 创建标签页
        self.tab_widget = QTabWidget()
        
        # 添加命令管理页
        self.command_page = QWidget()
        self.command_layout = QVBoxLayout()
        self.command_page.setLayout(self.command_layout)
        self.tab_widget.addTab(self.command_page, "命令管理")

        # 创建待办事项页面
        self.todo_page = ToDoList(self)
        self.tab_widget.addTab(self.todo_page, "待办事项")
        self.main_layout.addWidget(self.tab_widget)
        
        # 按钮区域
        self.button_layout = QHBoxLayout()
        self.add_command_button = QPushButton("添加命令")
        self.add_command_button.setFixedSize(120, 30)  # 设置按钮大小
        self.add_category_button = QPushButton("添加分类")
        self.add_category_button.setFixedSize(120, 30)  # 设置按钮大小
        self.search_box = QLineEdit()
        self.search_box.setPlaceholderText("搜索命令...")
        self.search_box.setFixedHeight(30)
        self.category_search_box = QLineEdit()
        self.category_search_box.setPlaceholderText("搜索分类...")
        self.category_search_box.setFixedSize(300, 30)
        self.category_search_box.setFocusPolicy(Qt.StrongFocus)

        self.button_layout.addWidget(self.add_command_button)
        self.button_layout.addWidget(self.add_category_button)
        self.button_layout.addWidget(self.category_search_box)
        self.button_layout.addWidget(self.search_box)
        self.command_layout.addLayout(self.button_layout)
        
        # 连接搜索框信号
        self.category_search_box.textChanged.connect(self.search_categories)

        # 快捷操作提示栏
        self.tip_layout = QHBoxLayout()
        self.tip_label = QLabel("提示: 双击命令复制 | Shift+右键直接复制 | Ctrl+C复制选中命令")
        self.tip_label.setStyleSheet("color: gray; font-size: 9pt;")
        self.tip_layout.addWidget(self.tip_label)
        self.command_layout.addLayout(self.tip_layout)

        # 内容区域
        self.content_tree = QTreeWidget()
        self.content_tree.setStyleSheet("QTreeWidget::item { margin-left: 10px; }")
        self.content_tree.setHeaderLabels(["序号", "标题", "次标题", "命令内容"])
        self.command_layout.addWidget(self.content_tree)
        
        # 设置列宽
        self.content_tree.setColumnWidth(0, 120)  # 序号列
        self.content_tree.setColumnWidth(1, 200)  # 标题列
        self.content_tree.setColumnWidth(2, 150)  # 次标题列
        # 命令内容列不设固定宽度，自动扩展到最右侧

        # 设置序号列的样式，添加右边距和交替颜色
        self.content_tree.setAlternatingRowColors(True)
        self.content_tree.setStyleSheet("""
            QTreeWidget::item:column(0) {
                padding-right: 10px;
            }
            QTreeWidget::item:column(0):alternate {
                background-color: #f0f0f0;
            }
        """)

        # 创建复制成功提示标签
        self.copy_label = QLabel("已复制到剪贴板", self)
        self.copy_label.setStyleSheet("background-color: rgba(0, 0, 0, 150); color: white; padding: 5px 10px; border-radius: 3px;")
        self.copy_label.setAlignment(Qt.AlignCenter)
        self.copy_label.hide()

        # 连接右键菜单信号
        self.content_tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.content_tree.customContextMenuRequested.connect(self.show_context_menu)
        
        # 连接双击信号
        self.content_tree.itemDoubleClicked.connect(self.copy_command_content)
        
        # 连接按钮信号
        self.add_command_button.clicked.connect(self.add_command)
        self.add_category_button.clicked.connect(self.add_category)
        
        # 连接搜索框信号
        self.search_box.textChanged.connect(self.search_commands)

        # 加载数据到树形结构
        self.update_tree_view()

    def load_commands(self):
        """从JSON文件加载命令"""
        if os.path.exists(self.json_file):
            try:
                with open(self.json_file, 'r', encoding='utf-8') as f:
                    self.commands_data = json.load(f)
                # 迁移旧数据格式
                self._migrate_old_data_format()
            except json.JSONDecodeError:
                self.commands_data = {"默认分类": {}}
        else:
            self.commands_data = {"默认分类": {}}
    
    def _migrate_old_data_format(self):
        """迁移旧数据格式到新格式"""
        for category_name, commands in self.commands_data.items():
            if isinstance(commands, dict):
                for command_name, command_data in commands.items():
                    # 如果命令数据是字符串，转换为新格式
                    if isinstance(command_data, str):
                        self.commands_data[category_name][command_name] = {
                            "sub_title": "",
                            "content": command_data
                        }

    def save_commands(self):
        """保存命令到JSON文件"""
        with open(self.json_file, 'w', encoding='utf-8') as f:
            json.dump(self.commands_data, f, ensure_ascii=False, indent=4)

    def search_categories(self, search_text):
        """搜索分类"""
        if not search_text.strip():
            # 如果搜索框为空，显示所有分类
            self.update_tree_view()
            return
            
        # 过滤分类
        filtered_categories = {}
        for category_name, commands in self.commands_data.items():
            if search_text.lower() in category_name.lower():
                filtered_categories[category_name] = commands
        
        # 更新树形视图显示过滤结果
        self.content_tree.clear()
        
        row_num = 1
        for category_name, commands in filtered_categories.items():
            category_item = QTreeWidgetItem([str(row_num), category_name, "", ""])
            category_item.setData(0, Qt.UserRole, "category")
            category_item.setForeground(0, QtGui.QColor("#A6329C"))  # 设置分类颜色
            category_item.setForeground(1, QtGui.QColor("#A6329C"))
            self.content_tree.addTopLevelItem(category_item)
            
            for command_name, command_data in commands.items():
                command_item = QTreeWidgetItem([
                    str(row_num), 
                    command_name, 
                    command_data.get("sub_title", ""), 
                    command_data.get("content", "")
                ])
                command_item.setData(0, Qt.UserRole, "command")
                category_item.addChild(command_item)
            
            row_num += 1
        
        # 展开所有分类
        self.content_tree.expandAll()

    def update_tree_view(self):
        """更新树形结构显示"""
        self.content_tree.clear()
        for category_name, commands in self.commands_data.items():
            category = QTreeWidgetItem()
            category.setText(0, category_name)
            category.setForeground(0, QtGui.QColor("#A6329C"))
            self.content_tree.addTopLevelItem(category)
            
            for idx, (command_name, command_data) in enumerate(commands.items(), 1):
                item = QTreeWidgetItem()
                item.setText(0, str(idx))
                item.setText(1, command_name)
                item.setText(2, command_data.get("sub_title", ""))  # 次标题
                item.setText(3, command_data.get("content", ""))  # 命令内容
                category.addChild(item)
            
            category.setExpanded(True)

    def show_context_menu(self, position):
        """显示右键菜单"""
        item = self.content_tree.itemAt(position)
        if not item:
            return

        menu = QMenu()
        copy_action = menu.addAction("复制命令内容")
        
        # 如果是命令项（不是分类），添加编辑和删除选项
        if item.parent():
            edit_action = menu.addAction("编辑")
            delete_action = menu.addAction("删除")
        else:  # 如果是分类，添加分类相关选项
            add_command_action = menu.addAction("添加命令")
            edit_category_action = menu.addAction("编辑分类")
            delete_category_action = menu.addAction("删除分类")

        action = menu.exec_(self.content_tree.viewport().mapToGlobal(position))
        
        if action:
            if action == copy_action:
                self.copy_command_content(item)
            elif item.parent() and action == edit_action:
                self.edit_command(item)
            elif item.parent() and action == delete_action:
                self.delete_command(item)
            elif not item.parent():
                if action == add_command_action:
                    self.add_command_to_category(item)
                elif action == edit_category_action:
                    self.edit_category(item)
                elif action == delete_category_action:
                    self.delete_category(item)

    def copy_command_content(self, item):
        """复制命令内容到剪贴板"""
        if item.parent():  # 确保是命令项而不是分类
            command_content = item.text(3)
            clipboard = QApplication.clipboard()
            clipboard.setText(command_content)
            
            # 显示复制成功提示
            self.copy_label.move(self.width() - 150, 50)
            self.copy_label.show()
            self.copy_label.raise_()
            
            # 3秒后自动隐藏
            from PyQt5.QtCore import QTimer
            QTimer.singleShot(3000, self.copy_label.hide)

    def add_command(self):
        """添加新命令"""
        # 获取当前选中的分类
        current_item = self.content_tree.currentItem()
        if current_item:
            category = current_item if not current_item.parent() else current_item.parent()
            category_name = category.text(0)
        else:
            category_name = "默认分类"

        dialog = CommandDialog(self)
        if dialog.exec_() == QDialog.Accepted:
            command_data = dialog.get_command_data()
            if command_data["name"] and command_data["content"]:
                if category_name not in self.commands_data:
                    self.commands_data[category_name] = {}
                self.commands_data[category_name][command_data["name"]] = {
                    "sub_title": command_data["sub_title"],
                    "content": command_data["content"]
                }
                self.save_commands()
                self.update_tree_view()
            else:
                QMessageBox.warning(self, "输入错误", "命令名称和内容不能为空")

    def edit_command(self, item):
        """编辑命令"""
        category_name = item.parent().text(0)
        command_name = item.text(1)
        sub_title = item.text(2)
        command_content = item.text(3)

        dialog = CommandDialog(self, command_name, command_content, sub_title)
        if dialog.exec_() == QDialog.Accepted:
            command_data = dialog.get_command_data()
            if command_data["name"] and command_data["content"]:
                # 如果命令名称改变了，需要删除旧的命令
                if command_data["name"] != command_name:
                    del self.commands_data[category_name][command_name]
                self.commands_data[category_name][command_data["name"]] = {
                    "sub_title": command_data["sub_title"],
                    "content": command_data["content"]
                }
                self.save_commands()
                self.update_tree_view()
            else:
                QMessageBox.warning(self, "输入错误", "命令名称和内容不能为空")

    def delete_command(self, item):
        """删除命令"""
        category_name = item.parent().text(0)
        command_name = item.text(1)
        
        reply = QMessageBox.question(self, "确认删除", 
                                   f"确定要删除命令 '{command_name}' 吗？",
                                   QMessageBox.Yes | QMessageBox.No)
        
        if reply == QMessageBox.Yes:
            del self.commands_data[category_name][command_name]
            self.save_commands()
            self.update_tree_view()

    def add_category(self):
        """添加新分类"""
        category_name, ok = QInputDialog.getText(self, "添加分类", "请输入分类名称:")
        if ok and category_name:
            if category_name in self.commands_data:
                QMessageBox.warning(self, "错误", "该分类已存在")
            else:
                self.commands_data[category_name] = {}
                self.save_commands()
                self.update_tree_view()

    def edit_category(self, item):
        """编辑分类"""
        old_category_name = item.text(0)
        new_category_name, ok = QInputDialog.getText(self, "编辑分类", 
                                                   "请输入新的分类名称:",
                                                   text=old_category_name)
        
        if ok and new_category_name and new_category_name != old_category_name:
            if new_category_name in self.commands_data:
                QMessageBox.warning(self, "错误", "该分类名称已存在")
            else:
                self.commands_data[new_category_name] = self.commands_data.pop(old_category_name)
                self.save_commands()
                self.update_tree_view()

    def add_command_to_category(self, item):
        """在指定分类中添加新命令"""
        category_name = item.text(0)
        
        # 使用CommandDialog添加命令
        dialog = CommandDialog(self)
        if dialog.exec_() == QDialog.Accepted:
            command_data = dialog.get_command_data()
            if command_data["name"] and command_data["content"]:
                if category_name not in self.commands_data:
                    self.commands_data[category_name] = {}
                    
                self.commands_data[category_name][command_data["name"]] = {
                    "content": command_data["content"],
                    "sub_title": command_data["sub_title"]
                }
                self.save_commands()
                self.update_tree_view()

    def delete_category(self, item):
        """删除分类"""
        category_name = item.text(0)
        if category_name == "默认分类":
            QMessageBox.warning(self, "错误", "不能删除默认分类")
            return
        
        command_count = len(self.commands_data[category_name])
        reply = QMessageBox.question(self, "确认删除", 
                                   f"确定要删除分类 '{category_name}' 及其包含的 {command_count} 个命令吗？",
                                   QMessageBox.Yes | QMessageBox.No)
        
        if reply == QMessageBox.Yes:
            del self.commands_data[category_name]
            self.save_commands()
            self.update_tree_view()

    def search_commands(self, text):
        """搜索命令"""
        if not text:  # 如果搜索框为空，显示所有内容
            self.update_tree_view()
            return
            
        self.content_tree.clear()
        for category_name, commands in self.commands_data.items():
            matching_commands = {}
            for command_name, command_data in commands.items():
                # 在命令名称、次标题和内容中搜索
                if (text.lower() in command_name.lower() or 
                    text.lower() in command_data.get("sub_title", "").lower() or
                    text.lower() in command_data.get("content", "").lower()):
                    matching_commands[command_name] = command_data
            
            # 如果该分类下有匹配的命令，创建分类节点
            if matching_commands:
                category = QTreeWidgetItem()
                category.setText(0, category_name)
                category.setForeground(0, QtGui.QColor("#A6329C"))
                self.content_tree.addTopLevelItem(category)
                
                # 添加匹配的命令
                for idx, (command_name, command_data) in enumerate(matching_commands.items(), 1):
                    item = QTreeWidgetItem()
                    item.setText(0, str(idx))
                    item.setText(1, command_name)
                    item.setText(2, command_data.get("sub_title", ""))
                    item.setText(3, command_data.get("content", ""))
                    category.addChild(item)
                
                category.setExpanded(True)



class ToDoList(QWidget):
    """待办事项列表 - 文本编辑器样式"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        
        # 设置数据文件路径 - 保存在C盘用户目录
        self.todo_file = os.path.join(os.path.expanduser("~"), "Documents", "command_tool_todo.txt")
        
        # 创建顶部工具栏
        self.create_toolbar()
        
        # 创建文本编辑器
        self.text_edit = QTextEdit()
        self.text_edit.setPlaceholderText("在这里输入您的待办事项...\n\n支持多行文本编辑，可以直接输入或粘贴内容")
        self.text_edit.setStyleSheet("""
            QTextEdit {
                font-family: "Microsoft YaHei", "Segoe UI";
                font-size: 11pt;
                line-height: 1.4;
                padding: 10px;
            }
        """)
        
        # 设置tab缩进为4个空格
        self.text_edit.setTabStopDistance(4 * self.text_edit.fontMetrics().horizontalAdvance(' '))
        
        # 设置Ctrl+S快捷键
        from PyQt5.QtGui import QKeySequence
        from PyQt5.QtWidgets import QShortcut
        shortcut = QShortcut(QKeySequence("Ctrl+S"), self.text_edit)
        shortcut.activated.connect(self.save_todo_data)
        
        self.layout.addWidget(self.text_edit)
        
        # 加载现有数据
        self.load_todo_data()
        
        # 连接文本变化信号，实现自动保存
        self.text_edit.textChanged.connect(self.on_text_changed)
        
        # 设置10秒自动保存定时器
        self.auto_save_timer = QTimer()
        self.auto_save_timer.timeout.connect(self.auto_save)
        self.auto_save_timer.start(10000)  # 10秒
        
        # 从主窗口获取自动保存设置
        if parent and hasattr(parent, 'auto_save_enabled'):
            self.auto_save_enabled = parent.auto_save_enabled
        else:
            self.auto_save_enabled = True
        
        # 根据设置启动或停止定时器
        if not self.auto_save_enabled:
            self.auto_save_timer.stop()

    def set_auto_save_enabled(self, enabled):
        """设置自动保存是否启用"""
        self.auto_save_enabled = enabled
        if enabled:
            self.auto_save_timer.start(10000)
        else:
            self.auto_save_timer.stop()

    def on_text_changed(self):
        """文本变化时的处理"""
        if self.auto_save_enabled:
            self.save_todo_data()

    def auto_save(self):
        """定时器触发的自动保存"""
        if self.auto_save_enabled:
            self.save_todo_data()

    def create_toolbar(self):
        """创建顶部工具栏"""
        toolbar_layout = QHBoxLayout()
        
        # 另存为按钮
        self.save_as_button = QPushButton("另存为")
        self.save_as_button.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 5px 10px;
                border-radius: 3px;
                font-size: 9pt;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """)
        self.save_as_button.clicked.connect(self.save_todo_as)
        toolbar_layout.addWidget(self.save_as_button)
        
        # 删除文件按钮
        self.delete_button = QPushButton("删除数据文件")
        self.delete_button.setStyleSheet("""
            QPushButton {
                background-color: #ff6b6b;
                color: white;
                border: none;
                padding: 5px 10px;
                border-radius: 3px;
                font-size: 9pt;
            }
            QPushButton:hover {
                background-color: #ff5252;
            }
        """)
        self.delete_button.clicked.connect(self.delete_todo_file)
        toolbar_layout.addWidget(self.delete_button)
        
        # 上次编辑时间显示
        self.last_edit_label = QLabel("上次编辑: 从未编辑")
        self.last_edit_label.setStyleSheet("color: #666; font-size: 9pt;")
        toolbar_layout.addWidget(self.last_edit_label)
        
        # 添加弹性空间
        toolbar_layout.addStretch()
        
        self.layout.addLayout(toolbar_layout)
    
    def load_todo_data(self):
        """加载待办事项数据"""
        try:
            if os.path.exists(self.todo_file):
                with open(self.todo_file, 'r', encoding='utf-8') as f:
                    content = f.read()
                    self.text_edit.setPlainText(content)
                
                # 更新上次编辑时间显示
                self.update_last_edit_time()
        except Exception as e:
            print(f"加载待办事项数据失败: {e}")
    
    def update_last_edit_time(self):
        """更新上次编辑时间显示"""
        try:
            if os.path.exists(self.todo_file):
                mtime = os.path.getmtime(self.todo_file)
                edit_time = datetime.datetime.fromtimestamp(mtime).strftime('%Y-%m-%d %H:%M:%S')
                self.last_edit_label.setText(f"上次编辑: {edit_time}")
            else:
                self.last_edit_label.setText("上次编辑: 从未编辑")
        except Exception as e:
            print(f"更新编辑时间失败: {e}")
    
    def save_todo_data(self):
        """保存待办事项数据"""
        try:
            # 确保目录存在
            os.makedirs(os.path.dirname(self.todo_file), exist_ok=True)
            
            content = self.text_edit.toPlainText()
            with open(self.todo_file, 'w', encoding='utf-8') as f:
                f.write(content)
            
            # 更新上次编辑时间显示
            self.update_last_edit_time()
        except Exception as e:
            print(f"保存待办事项数据失败: {e}")
    
    def save_todo_as(self):
        """另存为待办事项数据"""
        try:
            # 打开文件选择对话框
            file_path, _ = QFileDialog.getSaveFileName(
                self, 
                '另存为待办事项',
                os.path.expanduser("~"),
                '文本文件 (*.txt);;所有文件 (*)'
            )
            
            if file_path:
                content = self.text_edit.toPlainText()
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(content)
                
                QMessageBox.information(self, '保存成功', f'文件已保存到:\n{file_path}')
                
        except Exception as e:
            QMessageBox.critical(self, '保存失败', f'保存文件时出错: {e}')
            print(f"另存为待办事项数据失败: {e}")
    
    def delete_todo_file(self):
        """删除待办事项数据文件"""
        try:
            if os.path.exists(self.todo_file):
                reply = QMessageBox.question(self, '确认删除', 
                    '确定要删除待办事项数据文件吗？\n此操作不可撤销！',
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                
                if reply == QMessageBox.Yes:
                    os.remove(self.todo_file)
                    self.text_edit.clear()
                    self.last_edit_label.setText("上次编辑: 从未编辑")
                    QMessageBox.information(self, '删除成功', '待办事项数据文件已删除')
            else:
                QMessageBox.information(self, '提示', '待办事项数据文件不存在')
        except Exception as e:
            QMessageBox.critical(self, '删除失败', f'删除文件时出错: {e}')
            print(f"删除待办事项数据文件失败: {e}")

    def search_commands(self, text):
        """搜索命令"""
        if not text:  # 如果搜索框为空，显示所有内容
            self.update_tree_view()
            return
            
        self.content_tree.clear()
        for category_name, commands in self.commands_data.items():
            matching_commands = {}
            for command_name, command_content in commands.items():
                # 在命令名称和内容中搜索
                if (text.lower() in command_name.lower() or 
                    text.lower() in command_content.lower()):
                    matching_commands[command_name] = command_content
            
            # 如果该分类下有匹配的命令，创建分类节点
            if matching_commands:
                category = QTreeWidgetItem()
                category.setText(0, category_name)
                category.setForeground(0, QtGui.QColor("#A6329C"))
                self.content_tree.addTopLevelItem(category)
                
                # 添加匹配的命令
                for idx, (command_name, command_content) in enumerate(matching_commands.items(), 1):
                    item = QTreeWidgetItem()
                    item.setText(0, str(idx))
                    item.setText(1, command_name)
                    item.setText(2, "")  # 次标题暂时为空
                    item.setText(3, command_content)
                    category.addChild(item)
                
                category.setExpanded(True)


if __name__ == "__main__":
    # # 单实例检查
    # if is_already_running():
    #     # 已有实例在运行，静默退出
    #     sys.exit(0)
    
    app = QApplication(sys.argv)
    window = CommandManager()
    window.show()
    sys.exit(app.exec_())